package com.angle3d;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.os.SystemClock;


public class SceneRenderer implements GLSurfaceView.Renderer {

	private final float[] mBgColor = {0, 0, 0, 0};
	private final View3D mView;
	private float mLastTime = -1;
    
    public SceneRenderer(View3D view) {
    	mView = view;
    }
    
    public void setClearColor(float r, float g, float b, float a) {
    	mBgColor[0] = r;
    	mBgColor[1] = g;
    	mBgColor[2] = b;
    	mBgColor[3] = a;
    }
    
    @Override
	public void onDrawFrame(GL10 unused) {
		float now = 0.001f * SystemClock.uptimeMillis();
		if (mLastTime < 0) mLastTime = now;
		
    	float dt = now - mLastTime;
		mLastTime = now;
		
		//first update scene
		updateNode(mView.getScene(), dt);
		
		GLES20.glClearColor(mBgColor[0], mBgColor[1], mBgColor[2], mBgColor[3]);
		GLES20.glClearDepthf(1);
		GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
		
		if (mView == null) return;
		
		//first render opaque objects
		renderNode(mView.getScene(), false);
		
		//then render transparent objects
		GLES20.glDepthMask(false);
		renderNode(mView.getScene(), true);
		GLES20.glDepthMask(true);
	}
	
	private void updateNode(Node node, float dt) {
		if (node == null) return;
		
		if (node.isUpdatable()) {
			node.update(dt);
		}
		
		for (int i = 0; i < node.getChildCount(); ++i) {
			updateNode(node.getChild(i), dt);
		}
	}
	
	private void renderNode(Node node, boolean transparent) {
		if (node == null) return;
		
		if (node.isVisible() && (node.isTransparent() == transparent)) {
			node.render(mView);
		}
		
		for (int i = 0; i < node.getChildCount(); ++i) {
			renderNode(node.getChild(i), transparent);
		}
	}

	@Override
	public void onSurfaceChanged(GL10 unused, int width, int height) {
		GLES20.glViewport(0, 0, width, height);
	}

	@Override
	public void onSurfaceCreated(GL10 unused, EGLConfig config) {
		GLES20.glEnable(GLES20.GL_DEPTH_TEST);
		GLES20.glDepthFunc(GLES20.GL_LEQUAL);
		GLES20.glEnable(GLES20.GL_TEXTURE_2D);
		GLES20.glEnable(GLES20.GL_BLEND);
		GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
	}
}
